iT邦幫忙

2022 iThome 鐵人賽

DAY 23
0
Software Development

[Python QT] 玩玩 Pyside 的各種功能系列 第 23

【Day23】QRadioButton - 單選方格 續

  • 分享至 

  • xImage
  •  

我們繼續昨天的 Google 表單的單選方格, 這次我們把使用者有勾選到的選項印出來到提交按鈕右方, 這次因為我們需要知道有打勾的 RadioButton 是在哪一列哪一欄, 這樣才能知道勾選的是哪個問題哪個答案, 因此把左方的聽說讀寫變成一個 list, 等級也變成一個 list, 然後函示裡有關列或欄的長度全都用 list 的長度, 這樣以後假如要加新的列或欄, 只要直接在 ini 裡增加元素即可, 不用一個一個找有使用到數字的程式碼去改

import sys
from PySide6.QtWidgets import *
from PySide6.QtGui import *
from PySide6.QtCore import *

class MyWidget(QWidget):
    def __init__(self):
        super().__init__()
        self.gridLayout = QGridLayout()
        self.setLayout(self.gridLayout)
        self.btnGroups = []
        self.rowList = ["聽", "說", "讀", "寫"]
        self.colList = ["精通", "中等", "略懂", "不懂"]
        label = QLabel("英文能力")
        label.setFixedHeight(20)
        self.gridLayout.addWidget(label, 0, 0)
        self.addQuestionLayout()

        btn = QPushButton("提交")
        btn.clicked.connect(self.submit)
        self.gridLayout.addWidget(btn, 6, 0)
        clearBtn = QToolButton()
        clearBtn.setText("清除表單")
        clearBtn.setAutoRaise(True)
        clearBtn.clicked.connect(self.clearOption)
        self.gridLayout.addWidget(clearBtn, 6, 4)
        self.outputLabel = QLabel("")
        self.gridLayout.addWidget(self.outputLabel, 6, 1, 1, 3)

    def addQuestionLayout(self):
        for i in range(len(self.colList)):
            self.addQuestionLabels(self.colList[i], i+1)

        for i in range(len(self.rowList)):
            self.addQuestionButtons(self.rowList[i], i+2)

    def addQuestionLabels(self, question: str, col: int):
        label = QLabel(question)
        label.setFixedHeight(20)
        self.gridLayout.addWidget(label, 1, col)

    def addQuestionButtons(self, question: str, row: int):
        label = QLabel(question)
        self.gridLayout.addWidget(label, row, 0)
        btnGroup = QButtonGroup()
        for i in range(len(self.rowList)):
            tb = QRadioButton()
            self.gridLayout.addWidget(tb, row, i+1)
            btnGroup.addButton(tb, i)
        self.btnGroups.append(btnGroup)

    def submit(self):
        outText = ""
        for i in range(len(self.rowList)):
            for j in range(len(self.colList)):
                if self.btnGroups[i].button(j).isChecked():
                    outText = outText + self.rowList[i] + ": " + self.colList[j] + " "
        self.outputLabel.setText(outText)

    def clearOption(self):
        for btnGroup in self.btnGroups:
            checked = btnGroup.checkedButton()
            if (checked):
                btnGroup.setExclusive(False)
                checked.setChecked(False)
                btnGroup.setExclusive(True)

if __name__ == "__main__":
    app = QApplication([])
    QApplication.setApplicationName("語言能力")
    QApplication.setWindowIcon(QIcon("icon\clipboard-list.png"))
    widget = MyWidget()
    widget.resize(500, 300)
    widget.show()

    sys.exit(app.exec())

展示如下
1
因為在這裡已經把所有選項都放進 list 了, 所以加 Label 的函示又可以再簡化成 for 迴圈, 不用一個一個加, 程式碼看起來簡潔而且易修改~

接下來發現 Google 表單在設置單選方格問題時, 可以讓使用者一定要每一列都選擇才提交, 所以我們也在這個小程式裡達成這個功能吧!
我們在跟提交按鈕相連的函示裡多寫一個專門確認每一列是否都有被勾選到的函示

import sys
from PySide6.QtWidgets import *
from PySide6.QtGui import *
from PySide6.QtCore import *

class MyWidget(QWidget):
    def __init__(self):
        super().__init__()
        self.gridLayout = QGridLayout()
        self.setLayout(self.gridLayout)
        self.btnGroups = []
        self.rowList = ["聽", "說", "讀", "寫"]
        self.colList = ["精通", "中等", "略懂", "不懂"]
        label = QLabel("英文能力")
        label.setFixedHeight(20)
        self.gridLayout.addWidget(label, 0, 0)
        self.addQuestionLayout()

        btn = QPushButton("提交")
        btn.clicked.connect(self.submit)
        self.gridLayout.addWidget(btn, 6, 0)
        clearBtn = QToolButton()
        clearBtn.setText("清除表單")
        clearBtn.setAutoRaise(True)
        clearBtn.clicked.connect(self.clearOption)
        self.gridLayout.addWidget(clearBtn, 6, 4)
        self.outputLabel = QLabel("")
        self.gridLayout.addWidget(self.outputLabel, 6, 1, 1, 3)

    def addQuestionLayout(self):
        for i in range(len(self.colList)):
            self.addQuestionLabels(self.colList[i], i+1)

        for i in range(len(self.rowList)):
            self.addQuestionButtons(self.rowList[i], i+2)

    def addQuestionLabels(self, question: str, col: int):
        label = QLabel(question)
        label.setFixedHeight(20)
        self.gridLayout.addWidget(label, 1, col)

    def addQuestionButtons(self, question: str, row: int):
        label = QLabel(question)
        self.gridLayout.addWidget(label, row, 0)
        btnGroup = QButtonGroup()
        for i in range(len(self.rowList)):
            tb = QRadioButton()
            self.gridLayout.addWidget(tb, row, i+1)
            btnGroup.addButton(tb, i)
        self.btnGroups.append(btnGroup)

    def submit(self):
        outText = ""
        if(self.allRowChecked()):
            for i in range(len(self.rowList)):
                for j in range(len(self.colList)):
                    if self.btnGroups[i].button(j).isChecked():
                        outText = outText + self.rowList[i] + ": " + self.colList[j] + " "
            self.outputLabel.setText(outText)
            self.outputLabel.setStyleSheet("")
        else:
            self.outputLabel.setText("你必須針對每一列選取一個回覆")
            self.outputLabel.setStyleSheet("QLabel { color : red; }")

    def allRowChecked(self):
        allChecked = True
        for btnGroup in self.btnGroups:
            checked = btnGroup.checkedButton()
            if (checked):
                allChecked = allChecked * True
            else:
                allChecked = allChecked * False
        return allChecked

    def clearOption(self):
        for btnGroup in self.btnGroups:
            checked = btnGroup.checkedButton()
            if (checked):
                btnGroup.setExclusive(False)
                checked.setChecked(False)
                btnGroup.setExclusive(True)

if __name__ == "__main__":
    app = QApplication([])
    QApplication.setApplicationName("語言能力")
    QApplication.setWindowIcon(QIcon("icon\clipboard-list.png"))
    widget = MyWidget()
    widget.resize(500, 300)
    widget.show()

    sys.exit(app.exec())

為了有"提醒"的意思在, 提醒句特地設為紅色
最終展示如下
2


上一篇
【Day22】QRadioButton - 單選方格
下一篇
【Day24】QCommandLinkButton
系列文
[Python QT] 玩玩 Pyside 的各種功能31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言